package com.lcz.authority.admin.controller.system;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lcz.authority.admin.service.SysRoleService;
import com.lcz.authority.admin.service.SysUserService;
import com.lcz.authority.admin.web.service.SysPermissionService;
import com.lcz.authority.admin.web.service.TokenService;
import com.lcz.authority.common.annotation.ApiResource;
import com.lcz.authority.common.core.page.PageResult;
import com.lcz.authority.common.domain.R;
import com.lcz.authority.common.domain.entity.SysRoleEntity;
import com.lcz.authority.common.domain.entity.SysUserEntity;
import com.lcz.authority.common.domain.entity.SysUserRoleEntity;
import com.lcz.authority.common.domain.model.LoginUser;
import com.lcz.authority.common.enums.AppCodeEnum;
import com.lcz.authority.common.enums.ResBizTypeEnum;
import com.lcz.authority.common.utils.SecurityUtils;
import com.lcz.authority.common.utils.StringUtils;
import com.lcz.authority.common.utils.poi.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author lcz
 * @desc 角色管理控制器
 * @mail lcz_0130@163.com
 * @date 2024/05/06
 */

@RestController
@RequestMapping("/system/role")
@ApiResource(name = "角色管理", resBizType = ResBizTypeEnum.SYSTEM, appCode = AppCodeEnum.SYSTEMMODULES)
@Api(tags = "角色管理")
public class SysRoleController {

    @Autowired
    private SysRoleService roleService;
    @Autowired
    private SysUserService userService;
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    private TokenService tokenService;

    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping(value = "/list", name = "角色管理-查询角色列表")
    @ApiOperation("查询角色列表")
    public R list(SysRoleEntity role) {
        PageResult<SysRoleEntity> list = roleService.page(role);
        return R.ok().put(list);
    }

    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping(value = "/{roleId}", name = "角色管理-根据角色编号获取详细信息")
    @ApiOperation("根据角色编号获取详细信息")
    public R getInfo(@PathVariable String roleId) {
        return R.ok(roleService.selectRoleById(roleId));
    }

    @PreAuthorize("@ss.hasPermi('system:role:add')")
    @PostMapping(name = "角色管理-新增角色")
    @ApiOperation("新增角色")
    public R add(@Validated @RequestBody SysRoleEntity role) {
        if (!roleService.checkRoleNameUnique(role)) {
            return R.error("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        } else if (!roleService.checkRoleKeyUnique(role)) {
            return R.error("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        return R.ok(roleService.insertRole(role));
    }

    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PutMapping(name = "角色管理-修改保存角色")
    @ApiOperation("修改保存角色")
    public R edit(@Validated @RequestBody SysRoleEntity role) {
        roleService.checkRoleAllowed(role);
        roleService.checkRoleDataScope(role.getRoleId());
        if (!roleService.checkRoleNameUnique(role)) {
            return R.error("修改角色'" + role.getRoleName() + "'失败，角色名称已存在");
        } else if (!roleService.checkRoleKeyUnique(role)) {
            return R.error("修改角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        if (roleService.updateRole(role) > 0) {
            // 更新缓存用户权限
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) {
                loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
                loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
                tokenService.setLoginUser(loginUser);
            }
            //更新redis缓存权限数据
            permissionService.resetLoginUserRoleCache(role.getRoleId());
            return R.ok();
        }
        return R.error("修改角色'" + role.getRoleName() + "'失败，请联系管理员");
    }

    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PutMapping(value = "/changeStatus", name = "角色管理-状态修改")
    @ApiOperation("状态修改")
    public R changeStatus(@RequestBody SysRoleEntity role) {
        roleService.checkRoleAllowed(role);
        roleService.updateRoleStatus(role);
        //更新redis缓存权限数据
        permissionService.resetLoginUserRoleCache(role.getRoleId());
        return R.ok();
    }

    @PreAuthorize("@ss.hasPermi('system:role:remove')")
    @DeleteMapping(value = "/{roleIds}", name = "角色管理-删除角色")
    @ApiOperation("删除角色")
    public R remove(@PathVariable String[] roleIds) {
        roleService.deleteRoleByIds(roleIds);
        return R.ok();
    }

    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping(value = "/authUser/allocatedList", name = "角色管理-查询已分配用户角色列表")
    @ApiOperation("查询已分配用户角色列表")
    public R allocatedList(SysUserEntity user) {
        Page<SysUserEntity> page = userService.selectAllocatedList(user);
        return R.ok().put(page);
    }

    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping(value = "/authUser/unallocatedList", name = "角色管理-查询未分配用户角色列表")
    @ApiOperation("查询未分配用户角色列表")
    public R unallocatedList(SysUserEntity user) {
        Page<SysUserEntity> page = userService.selectUnallocatedList(user);
        return R.ok().put(page);
    }

    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PutMapping(value = "/authUser/cancel", name = "角色管理-取消授权用户")
    @ApiOperation("取消授权用户")
    public R cancelAuthUser(@RequestBody SysUserRoleEntity userRole) {
        int i = roleService.deleteAuthUser(userRole);
        //更新redis缓存权限数据
        permissionService.resetLoginUserRoleCache(userRole.getRoleId());
        return R.ok(i);
    }

    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PutMapping(value = "/authUser/cancelAll", name = "角色管理-批量取消授权用户")
    @ApiOperation("批量取消授权用户")
    public R cancelAuthUserAll(String roleId, String[] userIds) {
        int i = roleService.deleteAuthUsers(roleId, userIds);
        //更新redis缓存权限数据
        permissionService.resetLoginUserRoleCache(roleId);
        return R.ok(i);
    }

    @PreAuthorize("@ss.hasPermi('system:role:edit')")
    @PutMapping(value = "/authUser/selectAll", name = "角色管理-批量选择用户授权")
    @ApiOperation("批量选择用户授权")
    public R selectAuthUserAll(String roleId, String[] userIds) {
        return R.ok(roleService.insertAuthUsers(roleId, userIds));
    }

    @PreAuthorize("@ss.hasPermi('system:role:export')")
    @PostMapping(value = "/export", name = "角色管理-导出")
    @ApiOperation("导出角色数据")
    public void export(HttpServletResponse response, SysRoleEntity role) {
        List<SysRoleEntity> list = roleService.page(role).getRows();
        ExcelUtil<SysRoleEntity> util = new ExcelUtil<>(SysRoleEntity.class);
        util.exportExcel(response, list, "角色管理");
    }

}
